package org.me.marble;

import java.nio.*;

import java.util.ArrayList;
import javax.microedition.khronos.opengles.GL10;

/**
*
* @author tungi
*/

public class Marble extends GameObject{
    private FloatBuffer topBuffer,bottomBuffer,blanketBuffer; //vertices
    private FloatBuffer topTextureBuffer,bottomTextureBuffer,
                        blanketTextureBuffer;//textures
    
    private int res;
    private float radius=0.3f;
    
    public Marble(int id){
        super(id);
    }

    @Override
    public void init(){
        //get the objects quality
        if(OptionsLibrary.objects_quality.equals("low"))
            res=10;
        else if(OptionsLibrary.objects_quality.equals("medium"))
            res=20;
        else if(OptionsLibrary.objects_quality.equals("high"))
            res=30;
        //calculate coordinates of the sphere
        boolean pitch=true;
        Vector a,b;
        ArrayList<Float> blanket=new ArrayList<Float>();
        ArrayList<Float> top=new ArrayList<Float>();
        ArrayList<Float> bottom=new ArrayList<Float>();

        ArrayList<Float> blankettexture=new ArrayList<Float>();
        ArrayList<Float> toptexture=new ArrayList<Float>();
        ArrayList<Float> bottomtexture=new ArrayList<Float>();

        for(int i=0;i<=res;++i){
            pitch=true;
            for(int j=0;j<=res;++j){
               a=new Vector(
                    MyMath.makeRound(radius*(float)Math.sin(Math.PI*i/res)*
                                            (float)Math.cos(2*Math.PI*j/res),5),
                    MyMath.makeRound(radius*(float)Math.sin(Math.PI*i/res)*
                                            (float)Math.sin(2*Math.PI*j/res),5),
                    MyMath.makeRound(radius*(float)Math.cos(Math.PI*i/res),5));
               b=new Vector(
                    MyMath.makeRound(radius*(float)Math.sin(Math.PI*(i+1)/res)*
                                            (float)Math.cos(2*Math.PI*j/res),5),
                    MyMath.makeRound(radius*(float)Math.sin(Math.PI*(i+1)/res)*
                                            (float)Math.sin(2*Math.PI*j/res),5),
                    MyMath.makeRound(radius*(float)Math.cos(Math.PI*(i+1)/res),5));

               if((i==0 && pitch) || i==1){
                   bottom.add(a.getX());
                   bottom.add(a.getY());
                   bottom.add(a.getZ());

                   bottomtexture.add((float)i/res);
                   bottomtexture.add((float)j/res);
                   if(i==0)//add only once
                       pitch=false;
               }
               if((i==res && pitch) || i==(res-1)){
                   top.add(0,a.getX());
                   top.add(1,a.getY());
                   top.add(2,a.getZ());

                   toptexture.add(0,(float)i/res);
                   toptexture.add(1,(float)j/res);
                   if(i==res)//add only once
                       pitch=false;
               }
               if(i>0 && i<(res-1)){
                   blanket.add(a.getX());
                   blanket.add(a.getY());
                   blanket.add(a.getZ());

                   blankettexture.add((float)i/res);
                   blankettexture.add((float)j/res);

                   blanket.add(b.getX());
                   blanket.add(b.getY());
                   blanket.add(b.getZ());

                   blankettexture.add((float)(i+1)/res);
                   blankettexture.add((float)j/res);
               }
            }
        }
        
        topBuffer=BufferFactory.MakeFloatBuffer(top);
        bottomBuffer=BufferFactory.MakeFloatBuffer(bottom);
        blanketBuffer=BufferFactory.MakeFloatBuffer(blanket);
        
        topTextureBuffer=BufferFactory.MakeFloatBuffer(toptexture);
        bottomTextureBuffer=BufferFactory.MakeFloatBuffer(bottomtexture);
        blanketTextureBuffer=BufferFactory.MakeFloatBuffer(blankettexture);

        color=new MyColor();
        color.setAmbient(new float[]{(float)230/255,(float)232/255,(float)250/255,0.8f});
        color.setDiffuse(new float[]{(float)230/255,(float)232/255,(float)250/255,0.8f});
        color.setSpecular(new float[]{0.6f,0.6f,0.6f,0.5f});
        color.setEmission(new float[]{0.1f,0.1f,0.1f,0.5f});
        color.setShininess(1.0f);
    }

    

    @Override
    public void draw(GL10 gl){
        OpenGLSystem.enable(gl,//OpenGLSystem.CULL_FACE |
                OpenGLSystem.BLEND | OpenGLSystem.TEXTURE);
        OpenGLSystem.enableClientStates(gl,OpenGLSystem.NORMAL_ARRAY |
                OpenGLSystem.TEXTURE_ARRAY | OpenGLSystem.VERTEX_ARRAY);

        OpenGLSystem.setMaterial(gl,color);

        OpenGLSystem.drawTriangles(gl,texture,bottomBuffer,bottomBuffer,
                bottomTextureBuffer,res+2,GL10.GL_TRIANGLE_FAN);
        OpenGLSystem.drawTriangles(gl,texture,blanketBuffer,blanketBuffer,
                blanketTextureBuffer,2*(res+1)*(res-2),GL10.GL_TRIANGLE_STRIP);
        OpenGLSystem.drawTriangles(gl,texture,topBuffer,topBuffer,
                topTextureBuffer,res+2,GL10.GL_TRIANGLE_FAN);

        OpenGLSystem.disableClientStates(gl,OpenGLSystem.NORMAL_ARRAY |
                OpenGLSystem.TEXTURE_ARRAY | OpenGLSystem.VERTEX_ARRAY);
        OpenGLSystem.disable(gl,//OpenGLSystem.CULL_FACE |
                OpenGLSystem.BLEND | OpenGLSystem.TEXTURE);
    }    

    public float getRadius(){
        return radius;
    }
}
